//
//  HUDVC.swift
//  BWPanelKit
//
//  Created by zhuxuhong on 2022/3/7.
//

import BWUIKit
import BWExtensionKit
import BWToolKit

public class HUDVC: ViewController {
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var textLabel: UILabel!
    @IBOutlet weak var customWrapperView: UIView!
    @IBOutlet weak var contentWrapperView: UIView!
    @IBOutlet weak var positionStackView: UIStackView!
    
    var filterView: UserHitsCustomView? {
        return view as? UserHitsCustomView
    }
    
    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
    
    public convenience init(hud: HUD.Data, completion: BlockVoid?) {
        self.init(nibName: "\(Self.self)", bundle: Bundle.bw_podResourceBundle("BWHUDKit"))
        self.hud = hud
        self.completion = completion
    }
    
    public required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    var completion: BlockVoid?
    var hud: HUD.Data!
    
    public override func didLoad() {
        super.didLoad()
        
        setupStyles()
        setupHUDView()
        animateInitial()
    }
    
//    public override func didAppear() {
//        super.didAppear()
//
//        animateHUDView(isIn: true)
//    }
    
    public func setupStyles() {
        filterView?.isUserInteractionEnabled = hud.blockable
        view.backgroundColor = UIColor.clear
        imageView?.contentMode = .scaleAspectFit
        textLabel?.numberOfLines = 0
        textLabel?.font = HUD.shared.appearance.textFont
        textLabel?.textColor = HUD.shared.appearance.tintColor
        contentWrapperView?.backgroundColor = HUD.shared.appearance.backgroundColor
        contentWrapperView?.layer.cornerRadius = HUD.shared.appearance.cornerRadius
        customWrapperView?.backgroundColor = .clear
        
        switch hud.position {
        case .top:
            positionStackView?.alignment = .top
        case .center:
            positionStackView?.alignment = .center
        case .bottom:
            positionStackView?.alignment = .bottom
        }
    }
    
    public func animateInitial() {
        if let wrapperView = positionStackView {
            wrapperView.transform = .init(scaleX: 1.05, y: 1.05)
            wrapperView.alpha = 0
        }
    }
    
    public func setupHUDView()
    {
        switch (hud.customView, hud.icon, hud.text)
        {
        case (let customView, let icon, let text):
            imageView?.isHidden = icon == nil
            imageView?.image = icon
            textLabel?.isHidden = text == nil
            textLabel?.text = text
            
            customWrapperView?.isHidden = customView == nil
            contentWrapperView?.isHidden = customView != nil
            
            view.layoutIfNeeded()
            let h = contentWrapperView.height
            if h <= 50 {
                contentWrapperView.layer.cornerRadius = h/2
            }
            
            if let customView = customView,
               !customView.subviews.contains(customView)
            {
                filterView?.hitEnabledViews.append(customView)
                customWrapperView?.addSubview(customView)
                customView.snp.makeConstraints { make in
                    make.edges.equalToSuperview()
                }
            }
        }
    }
    
    @objc public func animateHUDView(isIn: Bool) {
        guard let wrapperView = positionStackView else {
            return
        }
        
        let duration = isIn ? 0.75 : 0.25
        let scale: CGFloat = isIn ? 1.0 : 1.05
        let alpha: CGFloat = isIn ? 1 : 0
        UIView.animate(
            withDuration: duration,
            delay: 0,
            usingSpringWithDamping: isIn ? 0.5 : 1,
            initialSpringVelocity: 1,
            options: [.curveEaseOut],
            animations: {
                wrapperView.transform = .init(scaleX: scale, y: scale)
                wrapperView.alpha = alpha
            },
            completion: animationCompleted(isIn: isIn)
        )
    }
    
    func animationCompleted(isIn: Bool) -> BlockT<Bool>? {
        return { [weak self] in
            guard $0, let self = self else { return }
            if isIn {
                if self.hud.duration.isFinite {
                    self.startClosing()
                }
            }
            else {
                self.view.removeFromSuperview()
                self.removeFromParent()
                self.completion?()
            }
        }
    }
    
    func startClosing(){
        perform(#selector(animateHUDView(isIn:)), with: false, afterDelay: hud.duration)
    }
    
    public func show() {
        var showVC = Lets.appCurrentVC
        if let ancestor = Lets.appCurrentVC?.ancestor {
            showVC = ancestor
        }
        guard let showVC = showVC else {
            return
        }
        
        view.frame = UIScreen.main.bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        showVC.view.addSubview(view)
        showVC.addChild(self)
        didMove(toParent: showVC)
        animateHUDView(isIn: true)
    }
    
    public func dismiss(completion: BlockVoid? = nil){
        if let selfCompletion = self.completion {
            self.completion = {
                selfCompletion()
                completion?()
            }
        }
        
        animateHUDView(isIn: false)
    }
    
    public override func willDisapppear() {
        super.willDisapppear()
        
        HUDVC.cancelPreviousPerformRequests(withTarget: self, selector: #selector(animateHUDView(isIn:)), object: nil)
    }
}

private extension UIViewController {
    var ancestor: UIViewController? {
        var parent = parent
        while parent?.parent != nil {
            parent = parent?.parent
        }
        return parent
    }
}
